package com.zhixun.mobile.modules.site.utils;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Hashtable;
import java.util.Random;
import java.util.UUID;

import javax.imageio.ImageIO;

import com.boxin.framework.base.utils.Constants;
import com.boxin.framework.base.utils.DateUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.thinkgem.jeesite.common.config.Global;
import com.zhixun.mobile.common.utils.FileUtils;

/**
 * @author Jakemanse
 * 二维码生成工具类
 */
public class QRCodeUtils {


	public   static final String QRCODE_JPG_URL_PRIX = "http://www.hdzhx.com/zxims/servlet/qrc?qrcodeId=";
	public   static final String QRCODE_PNG_URL_PRIX = "http://www.hdzhx.com/zxims/servlet/qrc?t=png&qrcodeId=";
	public   static final String QRCODE_PNG_PAGE_URL_PRIX = "http://www.hdzhx.com/zxims/f/wechat/lottery/viewqrcode?id=";
	private static final String  QRCODE_URL_GIFT_PRIX = "http://www.hdzhx.com/zxims/";

	public static final String ERROR_LEVEL_L =  "L";
	public static final String ERROR_LEVEL_M =  "M";
	public static final String ERROR_LEVEL_Q =  "Q";
	public static final String ERROR_LEVEL_H =  "H";
	public static final int WIDTH = 720;		//720
	public static final int HEIGHT = 400;		//400


	public static final String QRCODE_VTYPE_SECKILL = "SKL";
	public static final String QRCODE_VTYPE_LOTTERY = "LTR";
	public static final String QRCODE_VTYPE_EXCHANGE = "SEG";
	public static final String QRCODE_VTYPE_TICKET = "TCK";
	public static final String QRCODE_VTYPE_COUPON = "CPN";
	public static final String QRCODE_VTYPE_CIRCLE_SHARE = "CCS";
	public static final String QRCODE_VTYPE_PRAISE_ACTIVITY = "PRA";


	/**
	 * @author Jakemanse
	 * @time 2013-5-28  下午2:08:18
	 * @function <p> 生成png 图片 </p>
	 * @param content
	 * @param path
	 * @param width
	 * @param height
	 * @return
	 */
	public static boolean generateQRCodePNG(String content,String path,int width,int height){
		return generateQRCode("png",content,path,width,height);
	}


	/**
	 * @author Jakemanse
	 * @time 2014-1-28  下午11:33:40
	 * @function <p> 根据内容生成默认大小的 二维码  </p>
	 * @param content
	 * @return
	 */
	public static String  generateDefaultQRCodePNG(String content){
		//生成二维码
		String path = Constants.getWechatResourceSavePath();
		path += DateUtils.getTodayString()+File.separator+content;
		FileUtils.createDirectory(path);
		QRCodeUtils.generateQRCodePNG(content, path, WIDTH,HEIGHT);

		return path;
	}

	public static boolean generateQRCodeJPEG(String content,String path,int width,int height){
		return generateQRCode("jpeg",content,path,width,height);
	}

	private  static boolean   generateQRCode(String picType,String content,String path,int width,int height){
		try {
			File file = new File(path + "." + picType);
			// String str = new String(content.getBytes("GBK"), "ISO-8859-1");

			Hashtable<EncodeHintType, ErrorCorrectionLevel> hints = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
			// hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
			BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
					BarcodeFormat.QR_CODE, width, height, hints);
			MatrixToImageWriter.writeToFile(bitMatrix, picType, file);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * @author Jakemanse
	 * @time 2013-8-6  上午2:06:34
	 * @function <p>  容错率生成二维码 </p>
	 * @param picType
	 * @param content
	 * @param path
	 * @param width
	 * @param height
	 * @param errorCode
	 * @return
	 */
	public static boolean generateQRCodeWithErrorLevel(String picType,String content,String path,int width,int height,String errorCode){
		try {
			String picFormat = picType;
			File file = new File(path + "." + picFormat);
			// String str = new String(content.getBytes("GBK"), "ISO-8859-1");
			Hashtable hints = new Hashtable();
			hints.put(EncodeHintType.ERROR_CORRECTION, getErrorCorrectionLevelByCode(errorCode));
			BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
					BarcodeFormat.QR_CODE, width, height, hints);
			MatrixToImageWriter.writeToFile(bitMatrix, picFormat, file);

			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return false;
	}



	public static ErrorCorrectionLevel  getErrorCorrectionLevelByCode(String code){
		if("L".equals(code)){
			return ErrorCorrectionLevel.L;
		}else if("M".equals(code)){
			return ErrorCorrectionLevel.M;
		}else if("Q".equals(code)){
			return ErrorCorrectionLevel.Q;
		}else if("H".equals(code)){
			return ErrorCorrectionLevel.H;
		}else{
			return ErrorCorrectionLevel.M;
		}
	}



	public static File  downloadImg(String strurl,File file){
		try {
			//String site ="http://qr.liantu.com/api.php?text=http://www.hdzhx.com/zxims/f/gift/15.html&bg=FFFFFF&fg=000000&el=h&w=200&logo=http://42.96.189.145/upload/58.jpg";
			URL url = new URL(strurl);

			InputStream is = url.openStream();
			//File file = new File("D:\\temp\\myqrcode.jpg");
			if(!file.exists()){
				file.createNewFile();
			}

			BufferedInputStream bis = new BufferedInputStream(is);
			FileOutputStream fos  = new FileOutputStream(file);

			byte bytes[] = new byte[1024];
			int offset = 0;
			while ((offset = bis.read(bytes)) != -1) {
				fos.write(bytes, 0, offset);
			}


			fos.flush();
			fos.close();
			bis.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return file;
	}


	public static void main(String[] args) {
		String content = "Content ";
		String path = "D:\\temp\\QRCode\\";
		int width = 200;
		int height = 200;
		//		for(int i=0;i<10;i++){
		//			String str = content +i;
		//			String filepath = path + "testqrcode-"+i+".png";
		//			generateQRCodePNG(str, filepath, width+(i*10), height+i);
		//		}
		content = "http://192.168.1.102:8080/jeesite/f/mobsite/mom/pro/1.html";
		//		content = "";
		//		List<String> lines = FileUtils.readFileByLine(new File("D:\\temp\\temp2.txt"));
		//		for(String line : lines){
		//			content += line;
		//		}
		System.out.println("长度为"+content.length());
		generateQRCodePNG(content, path+"long_text", width, height);

	}



	public static String generateURL(Long projectId){
		return Global.DNS_TEMP + Global.MOBILE_SITE_PATH+"/mom/pro/"+projectId+".html";
	}

	public static String generateProjectURL(Long projectId){
		return Global.DNS +Global.CONTEXT_PATH + Global.MOBILE_SITE_PATH+"/mom/pro/"+projectId+".html";
	}

	/**
	 * @author Jakemanse
	 * @time 2013-7-1  下午2:47:12
	 * @function <p>  Base Path  即  http://localhost:80/zxims</p>
	 * @param basePath
	 * @param ecardId
	 * @return
	 */
	public static String generateEcardURL(String basePath, Long ecardId){
		return basePath  + Global.MOBILE_ECARD_PATH +"/"+ecardId+Global.URL_SUFFIX;
	}


	/**
	 * @author Jakemanse
	 * @time 2013-7-28  上午2:06:29
	 * @function <p> 生成礼物的URL如：http://www.hdzhx.com/zxims/f/gift/5.html </p>
	 * @param giftId
	 * @return
	 */
	public static String generateGiftURL(Long giftId){
		return Global.DNS + Global.CONTEXT_PATH + Global.MOBILE_GIFT_PATH +"/"+giftId+Global.URL_SUFFIX;
	}

	/**
	 * @author Jakemanse
	 * @time 2013-7-31  下午3:51:44
	 * @function <p> 生成旅游车队管理的URL 如：http://www.hdzhx.com/zxims/f/travel/bus/5.html </p>
	 * @param giftId
	 * @return
	 */
	public static String generateTravelBusURL(Long busId){
		String url = Global.DNS + Global.CONTEXT_PATH + Global.MOBILE_TRAVEL_BUS_PATH +"/view/"+busId+Global.URL_SUFFIX;
		String param = "?type=qrcodex$xp1="+System.currentTimeMillis()+getRandomString(50);
		return url + param;
	}


	public static String getRandomString(int len){
		StringBuffer sb = new StringBuffer();
		String [] chars = {"a","b","c","D","E","f","g","x","z","Y","U","I","D","H","j","Z","P","o","O"};
		Random rand = new Random();
		for(int i=0;i<len;i++){
			sb.append(rand.nextInt(10));
			//sb.append(chars[rand.nextInt(15)]);
		}
		return sb.toString();
	}


	/**
	 * @author Jakemanse
	 * @time 2013-6-24  上午11:36:57
	 * @function <p> 解析二维码  </p>
	 * @param file
	 * @return
	 */
	public static String decode(File file){
		try {
			String imgPath = "D:\\temp\\QRCode\\1367552294529.png";
			//			File file = new File(imgPath);
			BufferedImage image;
			try {
				image = ImageIO.read(file);
				if (image == null) {
					System.out.println("Could not decode image");
				}
				LuminanceSource source = new BufferedImageLuminanceSource(image);
				BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(
						source));
				Result result;
				Hashtable hints = new Hashtable();
				hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
				// 解码设置编码方式为：utf-8，
				result = new MultiFormatReader().decode(bitmap, hints);
				String resultStr = result.getText();
				System.out.println("解析后内容：" + resultStr);
				return resultStr;
			} catch (IOException ioe) {
				System.out.println(ioe.toString());
			} catch (ReaderException re) {
				System.out.println(re.toString());
			}

		} catch (Exception ex) {
			System.out.println(ex.toString());
		}

		return null;
	}



	public void encode(String contents, String imgPath, int width, int height) {  
		Hashtable  hints = new Hashtable<Object, Object>();  
		// 指定纠错等级  
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);  
		// 指定编码格式  
		hints.put(EncodeHintType.CHARACTER_SET, "GBK");  
		try { 
			BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);  
			MatrixToImageWriter  
			.writeToFile(bitMatrix, "png", new File(imgPath));  

		} catch (Exception e) {  
			e.printStackTrace();  
		}  
	}  





	/**
	 * @author Jakemanse
	 * @time 2013-7-22  上午11:37:26
	 * @function <p> 优惠券 序列号 </p>
	 * @param userId
	 * @return
	 */
	public static String  generateCouponSN(Long userId){
		StringBuffer sb = new StringBuffer();
		sb.append(QRCODE_VTYPE_COUPON).append(userId).append("-").append(generateUUID());
		return sb.toString();

	}

	/**
	 * @author Jakemanse
	 * @time 2013-10-3  上午2:37:21
	 * @function <p> 积分兑换 </p>
	 * @param userId
	 * @return
	 */
	public static String  generateScoreExchageSN(Long userId){
		StringBuffer sb = new StringBuffer();
		sb.append(QRCODE_VTYPE_EXCHANGE).append(userId).append("-").append(generateUUID());
		return sb.toString();
	}

	/**
	 * @author Jakemanse
	 * @time 2014-1-28  下午11:29:25
	 * @function <p> 入场券 </p>
	 * @param userId
	 * @return
	 */
	public static String  generateTicketSN(Long userId){
		StringBuffer sb = new StringBuffer();
		sb.append(QRCODE_VTYPE_TICKET).append(userId).append("-").append(generateUUID());
		return sb.toString();
	}

	/**
	 * @author Jakemanse
	 * @time 2013-9-28  下午3:08:51
	 * @function <p> 秒杀获得者 的二维码电子凭证  + 序列号  </p>
	 * @param userId
	 * @return
	 */
	public static String generateSeckillSN(Long userId){
		StringBuffer sb = new StringBuffer();
		sb.append(QRCODE_VTYPE_SECKILL).append(userId).append("-").append(generateUUID());
		return sb.toString();
	}

	/**
	 * @author Jakemanse
	 * @time 2013-9-30  下午3:29:40
	 * @function <p> 抽奖序列号 </p>
	 * @param userId
	 * @return
	 */

	public static String generateLotterySN(Long userId){
		StringBuffer sb = new StringBuffer();
		sb.append(QRCODE_VTYPE_LOTTERY).append(userId).append("-").append(generateUUID());
		return sb.toString();
	}


	/**
	 * @author Jakemanse
	 * @time 2013-10-2  下午11:00:06
	 * @function <p>微信朋友圈图片分享 </p>
	 * @param userId
	 * @return
	 */
	public static String generateCircleShareSN(Long userId){
		StringBuffer sb = new StringBuffer();
		sb.append(QRCODE_VTYPE_CIRCLE_SHARE).append(userId).append("-").append(generateUUID());
		return sb.toString();
	}


	/**
	 * @author Jakemanse
	 * @time 2014-1-3  下午11:01:07
	 * @function <p> 赞活动二维码  </p>
	 * @param userId
	 * @return
	 */
	public static String generatePraiseActivitySN(Long userId){
		StringBuffer sb = new StringBuffer();
		sb.append(QRCODE_VTYPE_PRAISE_ACTIVITY).append(userId).append("-").append(generateUUID());
		return sb.toString();
	}



	/**
	 * @author Jakemanse
	 * @time 2013-10-2  下午11:11:48
	 * @function <p> 生成唯一ID或序列号 </p>
	 * @return
	 */
	public  static String generateUUID(){
		String str = UUID.randomUUID().toString().toUpperCase();
		return str.replaceAll("-", "");
	}




	/**
	 * @author Jakemanse
	 * @time 2013-7-23  下午11:50:16
	 * @function <p> 二维码的下载路径 </p>
	 * @param qrCodeId
	 * @return
	 */
	public static String getQRCodeURL(Long qrCodeId){
		return QRCODE_JPG_URL_PRIX+qrCodeId+"&rnd="+System.currentTimeMillis();
	}

	/**
	 * @author Jakemanse
	 * @time 2013-10-3  上午12:19:21
	 * @function <p> 二维码图片的查看和下载路径  </p>
	 * @param qrCodeId
	 * @return
	 */
	public static String getQRCodePNGURL(Long qrCodeId){
		return QRCODE_PNG_URL_PRIX+qrCodeId+"&rnd="+System.currentTimeMillis();
	}

	/**
	 * @author Jakemanse
	 * @time 2013-11-26  下午11:16:34
	 * @function <p> 二维码电子凭证的浏览页面 </p>
	 * @param qrCodeId
	 * @return
	 */
	public static String getQRCodePNGPageURL(Long qrCodeId){
		return QRCODE_PNG_PAGE_URL_PRIX+qrCodeId+"&rnd="+System.currentTimeMillis();
	}

}
